﻿using System;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Windows;
using System.Windows.Threading;
using Downloader;
using System.Threading.Tasks;
namespace LauncherUpdate
{

	/// <summary>
	/// Interaction logic for MainWindow.xaml
	/// </summary>
	public partial class MainWindow : Window
	{
		DataContextBinding dataContext = new DataContextBinding();
		private DownloadFile downloader;
		public string downLoadUrl;
		string downloadZipPath;

		public MainWindow(String url)
		{
			InitializeComponent();
			ProgressBarControl.DataContext = dataContext;
			ProcessTextBlock.DataContext = dataContext;
			WindowM.DataContext = dataContext;
			background.DataContext = dataContext;
			downLoadUrl = url;
			Task task = DownloadAsync();
		}

		public void HideWindow()
		{
			dataContext.HideWindow = "Hidden";
			dataContext.ShowInBar = false;
		}
		public void ShowWindow()
		{
			dataContext.HideWindow = "Visable";
			dataContext.ShowInBar = true;
		}
		public async Task DownloadAsync()
		{
			string fileName = GetFileNameFromUrl(downLoadUrl);
			var mainFile = System.IO.Path.Combine(Directory.GetCurrentDirectory(), fileName);
			if (File.Exists(mainFile))
			{
				try
				{
					File.Delete(mainFile);
				}
				catch (Exception)
				{
				}
			}
			fileName = GetTempFileName(fileName);
			downloadZipPath = System.IO.Path.Combine(Directory.GetCurrentDirectory(), fileName);

			downloader = new DownloadFile()
			{
				Url = downLoadUrl,
				FilePath = downloadZipPath,
			};
			downloader.DownloadChange += DownloadChange;
			downloader.FinishDownload += DownloadFileCompleted;
			await downloader.StartAsync();
		}

		private void DownloadFileCompleted(object sender, EventArgs e)
		{
			dataContext.BarBindingVal = 0;
			dataContext.ProcessText = "";
			dataContext.ProgressBarVisable = "Hidden";

			downloadZipPath = ChangeFileName(downloadZipPath);

			// 开启静默安装
			OpenInstallExe();
		}
		private void OpenInstallExe()
		{
			if (File.Exists(downloadZipPath))
			{
				Process externalProcess = new Process();
				externalProcess.StartInfo.FileName = downloadZipPath;
				externalProcess.EnableRaisingEvents = true;
				externalProcess.StartInfo.Arguments = "/q"; // 启动静默安装
				externalProcess.StartInfo.WorkingDirectory = Directory.GetCurrentDirectory();
				if (externalProcess.Start())
				{
					HideWindow();
				}
				externalProcess.Exited += ExternalProcess_Exited;
				// ChangeComplete();
			}
		}
		private void ExternalProcess_Exited(object sender, EventArgs e)
		{
			App.Current.Dispatcher.Invoke((Action)delegate ()
			{
				try
				{
					if (File.Exists(downloadZipPath))
					{
						File.Delete(downloadZipPath);
					}
					this.Close();
				}
				catch (Exception) { }

			});


		}
		private void DownloadChange(object sender, DownloadData size)
		{
			var s = size;
			dataContext.BarBindingVal = s.Percent;
			dataContext.ProcessText = ("资源下载中 " + (int)s.Percent + "%");
		}

		void Button_Click_OpenLauncher(object sender, EventArgs e)
		{
			// OpenLauncher();
			this.Close();
		}
		void OpenLauncher()
		{
			string path = System.Environment.CurrentDirectory;
			DirectoryInfo pathInfo = new DirectoryInfo(path);
			var launcherPath = System.IO.Path.Combine(pathInfo.Parent.FullName, "IntoTheVoid.exe");
			if (File.Exists(launcherPath))
			{
				Process externalProcess = new Process();
				externalProcess.StartInfo.FileName = launcherPath;
				externalProcess.EnableRaisingEvents = true;
				externalProcess.StartInfo.WorkingDirectory = pathInfo.Parent.FullName;
				externalProcess.Start();
				this.Close();
			}
		}

		private void ChangeComplete()
		{
			Dispatcher.Invoke(() => ProgressBarControl.Visibility = Visibility.Hidden);
			Dispatcher.Invoke(() => OpenLauncherButton.Visibility = Visibility.Visible);
			Dispatcher.Invoke(() => ProcessTextBlock.Visibility = Visibility.Hidden);
		}

		void Button_Click_Close(object sender, RoutedEventArgs e)
		{
			OpenLauncher();
			this.Close();
		}

		void Button_Click_Mini(object sender, RoutedEventArgs e)
		{
			this.WindowState = WindowState.Minimized;
		}

		void Window_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
		{
			DragMove();
		}

		public string GetFileNameFromUrl(string url)
		{
			try
			{
				Uri uri = new Uri(url);
				string fileName = System.IO.Path.GetFileName(uri.LocalPath);
				return fileName;
			}
			catch (Exception)
			{
				return "";
			}
		}

		public string GetTempFileName(string fileName)
		{
			return System.IO.Path.GetFileNameWithoutExtension(fileName) + ".temp"; ;
		}

		public string ChangeFileName(string filePath)
		{
			var name = System.IO.Path.GetFileNameWithoutExtension(filePath);
			var directoryPath = System.IO.Path.GetDirectoryName(filePath);

			if (File.Exists(filePath))
			{
				string newName = name + ".exe";
				Microsoft.VisualBasic.FileSystem.Rename(filePath, newName);
				filePath = System.IO.Path.Combine(directoryPath, newName);
			}
			return filePath;
		}

		public class DataContextBinding : INotifyPropertyChanged
		{

			public event PropertyChangedEventHandler PropertyChanged;
			public void OnPropertyChanged(PropertyChangedEventArgs e)
			{
				if (PropertyChanged != null)
					PropertyChanged(this, e);
			}

			private float barBindingVal;
			public float BarBindingVal
			{
				get { return barBindingVal; }
				set
				{
					barBindingVal = value;
					OnPropertyChanged(new PropertyChangedEventArgs("BarBindingVal"));
				}
			}

			private string progressBarVisable = "Visable";
			public string ProgressBarVisable
			{
				get { return progressBarVisable; }
				set
				{
					progressBarVisable = value;
					OnPropertyChanged(new PropertyChangedEventArgs("ProgressBarVisable"));
				}
			}
			private string hideWindow = "Visable";
			public string HideWindow
			{
				get { return hideWindow; }
				set
				{
					hideWindow = value;
					OnPropertyChanged(new PropertyChangedEventArgs("HideWindow"));
				}
			}

			private string processText = "下载中";
			public string ProcessText
			{
				get { return processText; }
				set
				{
					processText = value;
					OnPropertyChanged(new PropertyChangedEventArgs("ProcessText"));
				}
			}
			private bool showInBar = true;
			public bool ShowInBar
			{
				get { return showInBar; }
				set
				{
					showInBar = value;
					OnPropertyChanged(new PropertyChangedEventArgs("ShowInBar"));
				}
			}
		}

	}
}